#pragma once

#include "DBManager/IRepository/Input/Table/ITABRND1Repository.h"
#include "DBManager/Repository/HDF5/Base/MainlyRepositoryBase.h"
#include "highfive/H5File.hpp"
SG_DBMANAGER_HDF5_NAMESPACE_OPEN
namespace TABRND1 {
struct IDENTITY {
  SG::DataStructure::Common::Id ID = 0;         ///<
  SG::DataStructure::Common::I64 CODEX = 0;     ///<
  SG::DataStructure::Common::I64 CODEY = 0;     ///<
  SG::DataStructure::Common::I64 POS = 0;       ///<
  SG::DataStructure::Common::I64 LEN = 0;       ///<
  SG::DataStructure::Common::Id DOMAIN_ID = 0;  ///<
};
};  // namespace TABRND1
SG_DBMANAGER_HDF5_NAMESPACE_CLOSE
template <>
inline HighFive::DataType
HighFive::create_datatype<SG::DBManager::HDF5::TABRND1::IDENTITY>() {
  HighFive::CompoundType compoundType = {
      {"ID", HighFive::create_datatype<SG::DataStructure::Common::Id>()},
      {"CODEX", HighFive::create_datatype<SG::DataStructure::Common::I64>()},
      {"CODEY", HighFive::create_datatype<SG::DataStructure::Common::I64>()},
      {"POS", HighFive::create_datatype<SG::DataStructure::Common::I64>()},
      {"LEN", HighFive::create_datatype<SG::DataStructure::Common::I64>()},
      {"DOMAIN_ID",
       HighFive::create_datatype<SG::DataStructure::Common::Id>()}};
  return compoundType;
}

template <>
inline HighFive::DataType
HighFive::create_datatype<SG::DataStructure::FEM::TABRND1Data::XYData>() {
  HighFive::CompoundType ct = {
      {"F", HighFive::create_datatype<SG::DataStructure::Common::Real>()},
      {"G", HighFive::create_datatype<SG::DataStructure::Common::Real>()}};
  return ct;
}
SG_DBMANAGER_HDF5_NAMESPACE_OPEN
class TABRND1Repository : public ITABRND1Repository,
                          public SG::DBManager::HDF5::MainlyRepositoryBase<
                              SG::DataStructure::FEM::TABRND1Data> {
  using MainStruct = SG::DataStructure::FEM::TABRND1Data;
  using SubStruct = SG::DataStructure::FEM::TABRND1Data::XYData;

  using NasMainStruct = SG::DBManager::HDF5::TABRND1::IDENTITY;

 public:
  explicit TABRND1Repository(HDF5Database& database);

  enum DATASET : std::uint8_t { MainDataset, IndexDataset, SubDataset };

  /**
   * @brief   : 初始化表数据
   * @author  : wuxingchuang
   */
  void InitialDatasetInfo() override;

  /**
   * @brief   : 将缓存数据转储到文件内
   */
  void DumpWriteCahce() override;

  /**
   * @brief   : 加载文件数据至缓存
   * @param   : loadIndex
   */
  std::vector<TABRND1Repository::DataType>* LoadReadCache(
      std::size_t loadIndex) override;

  /**
   * @brief   : 对数据进行排序
   */
  void SortData() override;

  /**
   * @brief   : 获取所有数据
   */
  std::vector<MainStruct> GetAllData() override;

  /**
   * @brief   : 将自己的数据转存为nastran的数据结构
   */
  void OwnToNastran(std::vector<MainStruct>& own,
                    std::vector<NasMainStruct>& _OUT IDENTITYData,
                    std::vector<SubStruct>& _OUT subData,

                    bool isSort = false);

  /**
   * @brief   : 将NASTRAN的数据转存为自己的数据结构
   * @param   : IDENTITYData
   * @param   : subData
   * @param   : own
   */
  void NastranToOwn(std::vector<NasMainStruct>& IDENTITYData,
                    std::vector<SubStruct>& subData,
                    std::vector<MainStruct>& _OUT own);
};
SG_DBMANAGER_HDF5_NAMESPACE_CLOSE
